#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""对象检查器组件"""

from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem,
    QMenu, QAction, QInputDialog, QMessageBox
)
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QFont, QColor, QBrush


class ObjectInspector(QWidget):
    """对象检查器组件"""
    
    # 组件选中信号
    component_selected = pyqtSignal(object)  # 传递选中的组件对象
    
    def __init__(self, parent=None):
        """初始化对象检查器"""
        super().__init__(parent)
        
        # 设置窗口属性
        self.setWindowTitle("对象检查器")
        self.setMinimumWidth(180)
        
        # 当前根组件
        self.root_component = None
        
        # 创建主布局
        main_layout = QVBoxLayout(self)
        
        # 创建对象树
        self.object_tree = QTreeWidget()
        self.object_tree.setHeaderLabel("对象")
        self.object_tree.setAlternatingRowColors(True)
        self.object_tree.setContextMenuPolicy(Qt.CustomContextMenu)
        
        # 添加到主布局
        main_layout.addWidget(self.object_tree)
        
        # 设置信号和槽
        self.setup_connections()
        
        # 创建上下文菜单
        self.create_context_menu()
    
    def setup_connections(self):
        """设置信号和槽的连接"""
        # 连接项目点击信号
        self.object_tree.itemClicked.connect(self.on_item_clicked)
        
        # 连接项目双击信号（用于重命名）
        self.object_tree.itemDoubleClicked.connect(self.on_item_double_clicked)
        
        # 连接上下文菜单信号
        self.object_tree.customContextMenuRequested.connect(self.show_context_menu)
    
    def create_context_menu(self):
        """创建上下文菜单"""
        self.context_menu = QMenu(self)
        
        # 添加重命名菜单项
        self.rename_action = QAction("重命名", self)
        self.rename_action.triggered.connect(self.rename_component)
        self.context_menu.addAction(self.rename_action)
        
        self.context_menu.addSeparator()
        
        # 添加剪切菜单项
        self.cut_action = QAction("剪切", self)
        self.cut_action.triggered.connect(self.cut_component)
        self.context_menu.addAction(self.cut_action)
        
        # 添加复制菜单项
        self.copy_action = QAction("复制", self)
        self.copy_action.triggered.connect(self.copy_component)
        self.context_menu.addAction(self.copy_action)
        
        # 添加粘贴菜单项
        self.paste_action = QAction("粘贴", self)
        self.paste_action.triggered.connect(self.paste_component)
        self.context_menu.addAction(self.paste_action)
        
        self.context_menu.addSeparator()
        
        # 添加删除菜单项
        self.delete_action = QAction("删除", self)
        self.delete_action.triggered.connect(self.delete_component)
        self.context_menu.addAction(self.delete_action)
    
    def set_root_component(self, root_component):
        """设置根组件"""
        self.root_component = root_component
        
        # 清空对象树
        self.object_tree.clear()
        
        if root_component is None:
            return
        
        # 创建根节点
        root_item = self.create_tree_item(root_component)
        self.object_tree.addTopLevelItem(root_item)
        root_item.setExpanded(True)
        
        # 递归添加子组件
        self.add_child_components(root_component, root_item)
    
    def create_tree_item(self, component):
        """创建树节点"""
        # 获取组件类名和对象名
        class_name = component.__class__.__name__
        object_name = component.objectName()
        
        # 如果没有对象名，使用类名
        display_text = f"{class_name}" if not object_name else f"{class_name} ({object_name})"
        
        # 创建树节点
        item = QTreeWidgetItem([display_text])
        
        # 存储组件对象
        item.setData(0, Qt.UserRole, component)
        
        # 设置字体（根节点使用粗体）
        font = item.font(0)
        if component == self.root_component:
            font.setBold(True)
        item.setFont(0, font)
        
        return item
    
    def add_child_components(self, parent_component, parent_item):
        """递归添加子组件"""
        # 获取所有子组件
        child_components = parent_component.findChildren(QWidget)
        
        for child in child_components:
            # 跳过隐藏的组件和窗口
            if not child.isVisible() or child.isWindow():
                continue
            
            # 创建子节点
            child_item = self.create_tree_item(child)
            parent_item.addChild(child_item)
            
            # 递归添加子节点的子组件
            self.add_child_components(child, child_item)
    
    def on_item_clicked(self, item, column):
        """处理项目点击事件"""
        # 获取组件对象
        component = item.data(0, Qt.UserRole)
        
        if component:
            # 发送组件选中信号
            self.component_selected.emit(component)
    
    def on_item_double_clicked(self, item, column):
        """处理项目双击事件"""
        # 双击根节点不进行重命名
        if item.data(0, Qt.UserRole) == self.root_component:
            return
        
        # 进入编辑状态
        self.object_tree.editItem(item, 0)
    
    def show_context_menu(self, position):
        """显示上下文菜单"""
        # 获取当前选中的项目
        selected_items = self.object_tree.selectedItems()
        
        if not selected_items:
            return
        
        # 显示上下文菜单
        self.context_menu.exec_(self.object_tree.mapToGlobal(position))
    
    def rename_component(self):
        """重命名组件"""
        # 获取当前选中的项目
        selected_items = self.object_tree.selectedItems()
        
        if not selected_items or len(selected_items) > 1:
            return
        
        item = selected_items[0]
        component = item.data(0, Qt.UserRole)
        
        # 不允许重命名根组件
        if component == self.root_component:
            QMessageBox.warning(self, "警告", "不能重命名根组件")
            return
        
        # 获取当前名称
        current_name = component.objectName()
        
        # 显示输入对话框
        new_name, ok = QInputDialog.getText(self, "重命名组件", "请输入新名称:", text=current_name)
        
        if ok and new_name and new_name != current_name:
            # 检查名称是否合法
            if not self.is_valid_object_name(new_name):
                QMessageBox.warning(self, "警告", "无效的对象名称")
                return
            
            # 检查名称是否已存在
            if self.is_name_exists(new_name, component.parent()):
                QMessageBox.warning(self, "警告", "对象名称已存在")
                return
            
            # 设置新名称
            component.setObjectName(new_name)
            
            # 更新树节点显示
            class_name = component.__class__.__name__
            item.setText(0, f"{class_name} ({new_name})")
    
    def cut_component(self):
        """剪切组件"""
        # 剪切功能实现
        QMessageBox.information(self, "信息", "剪切功能尚未实现")
    
    def copy_component(self):
        """复制组件"""
        # 复制功能实现
        QMessageBox.information(self, "信息", "复制功能尚未实现")
    
    def paste_component(self):
        """粘贴组件"""
        # 粘贴功能实现
        QMessageBox.information(self, "信息", "粘贴功能尚未实现")
    
    def delete_component(self):
        """删除组件"""
        # 获取当前选中的项目
        selected_items = self.object_tree.selectedItems()
        
        if not selected_items:
            return
        
        # 确认删除
        reply = QMessageBox.question(self, "确认删除", 
                                     f"确定要删除选中的 {len(selected_items)} 个组件吗？",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            for item in selected_items:
                component = item.data(0, Qt.UserRole)
                
                # 不允许删除根组件
                if component == self.root_component:
                    QMessageBox.warning(self, "警告", "不能删除根组件")
                    continue
                
                # 获取父节点
                parent_item = item.parent()
                
                if parent_item:
                    # 从父节点中移除
                    parent_item.removeChild(item)
                    
                    # 删除组件
                    if hasattr(self.parent(), 'canvas'):
                        self.parent().canvas.remove_component(component)
                    else:
                        component.deleteLater()
    
    def is_valid_object_name(self, name):
        """检查对象名称是否有效"""
        # 简单检查：名称不能为空，只能包含字母、数字、下划线，且不能以数字开头
        if not name or not name[0].isalpha() and name[0] != '_':
            return False
        
        for char in name[1:]:
            if not (char.isalnum() or char == '_'):
                return False
        
        return True
    
    def is_name_exists(self, name, parent_component):
        """检查名称是否已存在"""
        if not parent_component:
            parent_component = self.root_component
        
        # 查找具有相同名称的子组件
        children = parent_component.findChildren(QWidget)
        for child in children:
            if child.objectName() == name:
                return True
        
        return False
    
    def select_component(self, component):
        """选择指定的组件"""
        # 递归查找包含指定组件的树节点
        def find_item_with_component(item, target_component):
            if item.data(0, Qt.UserRole) == target_component:
                return item
            
            for i in range(item.childCount()):
                child_item = item.child(i)
                found_item = find_item_with_component(child_item, target_component)
                if found_item:
                    return found_item
            
            return None
        
        # 遍历顶层节点
        for i in range(self.object_tree.topLevelItemCount()):
            top_item = self.object_tree.topLevelItem(i)
            found_item = find_item_with_component(top_item, component)
            
            if found_item:
                # 选中节点
                self.object_tree.setCurrentItem(found_item)
                
                # 确保节点可见
                self.object_tree.scrollToItem(found_item, QTreeWidget.PositionAtTop)
                
                # 展开所有父节点
                parent_item = found_item.parent()
                while parent_item:
                    parent_item.setExpanded(True)
                    parent_item = parent_item.parent()
                
                break